export interface DanmakuItem {
  id: number;
  text: string;
  x: number;
  y: number;
  speed: number; // 像素/秒
  opacity: number;
  fontSize: number;
  fontFamily: string;
  color: string;
  mode: 'scroll' | 'bottom' | 'top';
  timestamp: number;
  lastUpdateTime: number; // 上次更新时间
}

export interface DanmakuConfig {
  opacity?: number;
  speedRange?: [number, number];
  fontSize?: number;
  fontFamily?: string;
  color?: string;
  fixedSpeed?: number; // 固定速度，不使用随机
}

export type GlobalDisplayMode = 'scroll' | 'top' | 'bottom';

export class DanmakuController {
  private canvas: HTMLCanvasElement;
  private ctx: CanvasRenderingContext2D;
  private config: DanmakuConfig;
  private animationId: number | null = null;
  private isRunning = false;
  private danmakuList: DanmakuItem[] = [];
  private trackPositions: number[] = [];
  private globalDisplayMode: GlobalDisplayMode = 'scroll';
  private lastFrameTime: number = 0;
  private isEnabled = true; // 弹幕开关状态

  constructor(canvas: HTMLCanvasElement, width: number, height: number, config: DanmakuConfig = {}) {
    this.canvas = canvas;
    this.config = {
      opacity: 0.8,
      speedRange: [80, 120], // 默认中等速度范围，与UI保持一致
      fontSize: 20,
      fontFamily: 'Arial, sans-serif',
      color: '#ffffff',
      fixedSpeed: 100, // 默认固定速度
      ...config
    };

    const ctx = this.canvas.getContext('2d');
    if (!ctx) throw new Error('Canvas 2D context not available');
    this.ctx = ctx;

    // 设置canvas尺寸
    this.canvas.width = width;
    this.canvas.height = height;

    // 初始化轨道位置
    this.initTracks();
  }

  private initTracks(): void {
    const lineHeight = this.config.fontSize! + 10;
    const trackCount = Math.floor(this.canvas.height / lineHeight);
    this.trackPositions = Array.from({ length: trackCount }, (_, i) => i * lineHeight + this.config.fontSize!);
  }

  start(): void {
    if (this.isRunning) return;
    this.isRunning = true;
    this.tick();
  }

  stop(): void {
    this.isRunning = false;
    if (this.animationId) {
      cancelAnimationFrame(this.animationId);
      this.animationId = null;
    }
  }

  send(text: string): void {
    if (!text || !text.trim() || !this.isEnabled) return;
    
    // 根据全局显示模式确定初始Y位置
    let initialY = this.getRandomY(); // 默认随机位置
    
    if (this.globalDisplayMode === 'top') {
      initialY = this.getTopY();
    } else if (this.globalDisplayMode === 'bottom') {
      initialY = this.getBottomY();
    }
    
    const item: DanmakuItem = {
      id: Date.now() + Math.random(),
      text: text.trim(),
      mode: this.globalDisplayMode, // 使用全局显示模式
      x: this.canvas.width + 20, // 从视频区域右侧外20px开始，确保完全进入视野
      y: initialY,
      speed: this.config.fixedSpeed!, // 使用固定速度 (像素/秒)
      opacity: this.config.opacity!,
      fontSize: this.config.fontSize!,
      fontFamily: this.config.fontFamily!,
      color: this.getRandomColor(),
      timestamp: Date.now(),
      lastUpdateTime: performance.now()
    };
    
    // console.log('创建新弹幕，速度设置为:', this.config.fixedSpeed, 'px/s');

    this.danmakuList.push(item);
  }

  clear(): void {
    this.danmakuList = [];
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }

  resize(width: number, height: number): void {
    this.canvas.width = width;
    this.canvas.height = height;
    this.initTracks();
  }

  setOpacity(opacity: number): void {
    this.config.opacity = Math.max(0, Math.min(1, opacity));
  }

  setSpeedRange(range: [number, number]): void {
    this.config.speedRange = range;
    // 使用范围的中点作为固定速度
    const newSpeed = (range[0] + range[1]) / 2;
    this.config.fixedSpeed = newSpeed;
    
    // 实时更新所有正在显示的弹幕速度
    this.danmakuList.forEach(item => {
      item.speed = newSpeed;
    });
    // console.log('通过setSpeedRange更新所有弹幕速度为:', newSpeed, 'px/s');
  }

  setFixedSpeed(speed: number): void {
    this.config.fixedSpeed = speed;
    // console.log('弹幕控制器速度已设置为:', speed, 'px/s');
    
    // 实时更新所有正在显示的弹幕速度
    this.danmakuList.forEach(item => {
      item.speed = speed;
    });
    // console.log('已更新', this.danmakuList.length, '个正在显示的弹幕速度');
  }

  setGlobalDisplayMode(mode: GlobalDisplayMode): void {
    this.globalDisplayMode = mode;
  }

  setEnabled(enabled: boolean): void {
    this.isEnabled = enabled;
    if (!enabled) {
      // 关闭弹幕时清空所有弹幕
      this.clear();
    }
  }

  getEnabled(): boolean {
    return this.isEnabled;
  }

  private tick(): void {
    if (!this.isRunning) return;

    const currentTime = performance.now();
    const deltaTime = this.lastFrameTime ? (currentTime - this.lastFrameTime) / 1000 : 0; // 转换为秒
    this.lastFrameTime = currentTime;

    // 清除画布
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

    // 如果弹幕关闭，只清除画布不渲染弹幕
    if (!this.isEnabled) {
      this.animationId = requestAnimationFrame(() => this.tick());
      return;
    }

    // 更新和渲染弹幕
    for (let i = this.danmakuList.length - 1; i >= 0; i--) {
      const item = this.danmakuList[i];
      
      // 根据全局显示模式调整弹幕的Y位置（轨道），但保持滚动效果
      if (this.globalDisplayMode === 'top') {
        // 顶部模式：弹幕在顶部轨道滚动
        item.y = this.getTopY();
      } else if (this.globalDisplayMode === 'bottom') {
        // 底部模式：弹幕在底部轨道滚动
        item.y = this.getBottomY();
      } else {
        // 滚动模式：弹幕在随机轨道滚动（保持原有位置或重新分配）
        if (item.mode === 'scroll') {
          // 保持原有随机位置
        } else {
          // 将固定位置的弹幕转换为随机轨道
          item.y = this.getRandomY();
        }
      }
      
      // 基于时间的移动：速度单位是像素/秒
      if (deltaTime > 0) {
        item.x -= item.speed * deltaTime;
      }
      
      // 移除已经离开视频区域的弹幕
      // 使用视频播放器的实际尺寸（750px × 370px）作为边界
      const textWidth = this.measureText(item.text);
      if (item.x + textWidth < -20) { // 弹幕完全离开视频区域后消失
        this.danmakuList.splice(i, 1);
        continue;
      }

      this.renderDanmaku(item);
    }

    this.animationId = requestAnimationFrame(() => this.tick());
  }

  private renderDanmaku(item: DanmakuItem): void {
    this.ctx.save();
    this.ctx.globalAlpha = item.opacity;
    this.ctx.font = `${item.fontSize}px ${item.fontFamily}`;
    this.ctx.fillStyle = item.color;
    this.ctx.textBaseline = 'middle';
    
    // 检查是否包含表情符号
    const hasEmoji = this.containsEmoji(item.text);
    
    if (hasEmoji) {
      // 对于包含表情的文本，使用更大的字体和不同的渲染方式
      this.ctx.font = `${item.fontSize * 1.2}px ${item.fontFamily}`;
      
      // 表情不需要描边，直接渲染
      this.ctx.fillText(item.text, item.x, item.y);
    } else {
      // 普通文本添加描边效果
      this.ctx.strokeStyle = 'rgba(0,0,0,0.7)';
      this.ctx.lineWidth = 2;
      this.ctx.strokeText(item.text, item.x, item.y);
      this.ctx.fillText(item.text, item.x, item.y);
    }
    
    this.ctx.restore();
  }

  private measureText(text: string): number {
    // 使用与渲染时相同的字体设置
    this.ctx.font = `${this.config.fontSize}px ${this.config.fontFamily}`;
    const metrics = this.ctx.measureText(text);
    return metrics.width;
  }

  private getRandomY(): number {
    return this.trackPositions[Math.floor(Math.random() * this.trackPositions.length)];
  }

  private getBottomY(): number {
    return this.canvas.height - 30;
  }

  private getTopY(): number {
    return 30;
  }

  private getRandomSpeed(): number {
    const [min, max] = this.config.speedRange!;
    // 生成随机速度，确保每个弹幕都有不同的固定速度
    const speed = min + Math.random() * (max - min);
    return Math.round(speed * 100) / 100; // 保留两位小数，让速度差异更精确
  }

  private getRandomColor(): string {
    const colors = [
      '#ffffff', '#ffff00', '#ff0000', '#00ff00', '#00ffff',
      '#ff00ff', '#ffa500', '#ff69b4', '#00ff7f', '#ffd700'
    ];
    return colors[Math.floor(Math.random() * colors.length)];
  }

  private containsEmoji(text: string): boolean {
    // 检测文本是否包含表情符号
    const emojiRegex = /[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/u;
    return emojiRegex.test(text);
  }
}
